/*
 * Copyright (C) 2015 Apple Inc. All rights reserved.
 *
 * This document is the property of Apple Inc.
 * It is considered confidential and proprietary.
 *
 * This document may not be reproduced or transmitted in any form,
 * in whole or in part, without the express written permission of
 * Apple Inc.
 */
#include <debug.h>
#include <lib/env.h>
#include <lib/paint.h>
#include <lib/syscfg.h>
#include <drivers/prc.h>
#include "prc.h"


static const uint32_t prc_prcLUT[256] =
       {0, 	64,	128,	192,	256,	320,	384,	448,
	512,    576,  	640,    704,    768,    832,    896,    960,
	1024,   1088,   1152,   1216,   1280,   1344,   1408,   1472,
	1536,   1600,  	1664,   1728,   1792,   1856,   1920,   1984,
	2048,   2112,  	2176,   2240,   2304,   2368,   2432,   2496,
	2560,   2624,  	2688,   2752,   2816,   2880,   2944,   3008,
	3072,   3136,  	3200,   3264,   3328,   3392,   3456,   3520,
	3584,   3648,  	3712,   3776,   3840,   3904,   3968,   4032,
	4096,   4160,  	4224,   4288,   4352,   4416,   4480,   4544,
	4608,   4672,  	4736,   4800,   4864,   4928,   4992,   5056,
	5120,  	5184,  	5248,   5312,   5376,   5440,   5504,   5568,
	5632,   5696,  	5760,   5824,   5888,   5952,   6016,   6080,
	6144,   6208,  	6272,   6336,   6400,   6464,   6528,   6592,
	6656,   6720,  	6784,   6848,   6912,   6976,   7040,   7104,
	7168,   7232,   7296,   7360,   7424,   7488,   7552,   7616,
	7680,   7744,  	7808,   7872,   7936,   8000,   8064,   8128,
	8192,   8256,  	8320,   8384,   8448,   8512,   8576,   8640,
	8704,   8768,  	8832,   8896,   8960,   9024,   9088,   9152,
	9216,   9280,  	9344,   9408,   9472,   9536,   9600,   9664,
	9728,   9792,  	9856,   9920,   9984,   10048,  10112,  10176, 
	10240,  10304,  10368,  10432,  10496,  10560,  10624,  10688, 
	10752,  10816,  10880,  10944,  11008,  11072,  11136,  11200, 
	11264,  11328,  11392,  11456,  11520,  11584,  11648,  11712, 
	11776,  11840,  11904,  11968,  12032,  12096,  12160,  12224, 
	12288,  12352,  12416,  12480,  12544,  12608,  12672,  12736, 
	12800,  12864,  12928,  12992,  13056,  13120,  13184,  13248, 
	13312,  13376,  13440,  13504,  13568,  13632,  13696,  13760, 
	13824,  13888,  13952,  14016,  14080,  14144,  14208,  14272, 
	14336,  14400,  14464,  14528,  14592,  14656,  14720,  14784, 
	14848,  14912,  14976,  15040,  15104,  15168,  15232,  15296, 
	15360,  15424,  15488,  15552,  15616,  15680,  15744,  15808, 
	15872,  15936,  16000,  16064,  16128,  16192,  16256,  16320 };

void prc_write_reg(uint32_t reg, uint32_t value);
uint32_t prc_read_reg(uint32_t reg);

void prc_init(uint32_t display_width, uint32_t display_height)
{
	// WPC Configuration defined in ADBE TRM v0.1.14. Section 4.4
	
	// Active Region Start
	prc_write_reg(PRC_CONFIG_ACTIVE_REGION_START_OFFSET, 
		PRC_CONFIG_ACTIVE_REGION_START_START_X_INSRT(0) | 
		PRC_CONFIG_ACTIVE_REGION_START_START_Y_INSRT(0));
	
	// Active Region Size
	prc_write_reg(PRC_CONFIG_ACTIVE_REGION_SIZE_OFFSET, 
		PRC_CONFIG_ACTIVE_REGION_SIZE_WIDTH_INSRT(display_width) | 
		PRC_CONFIG_ACTIVE_REGION_SIZE_HEIGHT_INSRT(display_height));

	//force update due to double buffer registers
	prc_write_reg(PRC_CONFIG_UPDATE_CONTROL_OFFSET, 0x3);
}

void prc_install_gamma_table(u_int32_t *red_lut, u_int32_t *green_lut, u_int32_t *blue_lut, struct syscfg_wpcl *wpcl)
{
	for (int i = 0; i < PRC_LUT_REG_COUNT; i++) {
		prc_write_reg(PRC_LUT_REG_OFFSET(i), prc_prcLUT[i % 256]);
	}
	
	for (int i = 0; i < PRC_LUT_LAST_COUNT; i ++) {
		prc_write_reg(PRC_LUT_LAST_OFFSET_V1(i), 16384);
	}
}

void prc_write_reg(uint32_t reg, uint32_t value)
{
	(*(volatile u_int32_t *)(PRC_BASE_ADDR + reg)) = value;
}

uint32_t prc_read_reg(uint32_t reg)
{
	return (*(volatile u_int32_t *)(PRC_BASE_ADDR + reg));
}
